
package com.insigma.business.qrcode.soldier._provider.impl;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import com.insigma.business.qrcode.common.dao.CommonAdminAreaDO;
import com.insigma.business.qrcode.common._provider.CommonAdminAreaProvider;
import com.insigma.business.qrcode.common.service.CommonAdminAreaService;
import com.insigma.business.qrcode.common.template.BasePagingResponse;
import com.insigma.business.qrcode.common.util.*;
import com.insigma.business.qrcode.common.vo.BaseDeleteRequest;
import com.insigma.business.qrcode.common.vo.BaseResponse;
import com.insigma.business.qrcode.soldier._provider.SoldierTpAllProvider;
import com.insigma.business.qrcode.soldier._provider.SoldierUnemploymentRegistrationInfoProvider;
import com.insigma.business.qrcode.soldier.dto.*;
import com.insigma.business.qrcode.soldier.dto.gov.BaseProviderImpl;
import com.insigma.business.qrcode.common.template.area.ScenarioCodeEnum;
import com.insigma.business.qrcode.common.template.area.ServiceCallback;
import com.insigma.business.qrcode.soldier.entity.*;
import com.insigma.business.qrcode.soldier.request.*;
import com.insigma.business.qrcode.soldier.service.*;
import com.insigma.business.qrcode.soldier.service.impl.SoldierDataBuffer;
import com.insigma.business.qrcode.soldier.service.impl.SoldierExtraInfoRefresher;
import com.insigma.business.qrcode.common.converter.SoldierTpAllProviderConverter;
import com.insigma.business.qrcode.soldier.util.IScrollGet;
import com.insigma.business.qrcode.soldier.util.RedisLock;
import com.insigma.business.qrcode.soldier.util.ThirdPartyDealUtils;
import com.insigma.business.qrcode.common.dto.ErrorCodeEnum;

import com.insigma.business.qrcode.soldier.util.ThreadPoolManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.httpclient.util.DateUtil;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.InputStream;
import java.net.URL;
import java.util.*;


@Slf4j
@Service
@Component("soldierTpAllProvider")
public class SoldierTpAllProviderImpl extends BaseProviderImpl implements SoldierTpAllProvider {

    @Autowired
    private SoldierTpAllService soldierTpAllService;

    @Autowired
    private RedisLock redisLock;

    @Autowired
    private SoldierDataBuffer soldierDataBuffer;

    @Autowired
    @Lazy
    private SoldierExtraInfoRefresher soldierExtraInfoRefresher;

    @Autowired
    private CommonTmpInfoService commonTmpInfoService;

    @Autowired
    private CommonAdminAreaService commonAdminAreaService;

    @Autowired
    @Lazy
    private SoldierUnemploymentRegistrationInfoProvider soldierUnemploymentRegistrationInfoProvider;


    @Autowired
    private ThirdPartyService thirdPartyService;

    @Autowired
    private CommonAdminAreaProvider commonAdminAreaProvider;


    @Override
    public BasePagingResponse<List<SoldierTpAllDTO>> searchSoldierTpAll(final SoldierTpAllSearchRequest searchRequest) {

        final BasePagingResponse<List<SoldierTpAllDTO>> basePagingResponse = new BasePagingResponse<>();
        serviceTemplate.execute(basePagingResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(searchRequest, "查询分页SoldierTpAll的请求参数不能为空");
            }

            @Override
            public void executeService() {
                final SoldierTpAllBSearcher soldierTpAllBSearcher = SoldierTpAllProviderConverter.convertRequestSO2Searcher(searchRequest);
                final List<SoldierTpAllDO> soldierTpAllDOList = soldierTpAllService.search(soldierTpAllBSearcher);
                final List<SoldierTpAllDTO> soldierTpAllDTOList = SoldierTpAllProviderConverter.convertResponseDOList2DTOList(soldierTpAllDOList);
                ResponseUtils.buildSuccessPagingResponse(basePagingResponse, soldierTpAllDTOList, searchRequest, soldierTpAllBSearcher.getTotalCount());
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.SOLDIER_TP_ALL_SEARCH;
            }
        });

        return basePagingResponse;
    }



    @Override
    public BaseResponse<SoldierTpAllDTO> getSoldierTpAll(final BaseGetRequest baseGetRequest) {

        final BaseResponse<SoldierTpAllDTO> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(baseGetRequest, "获取单条SoldierTpAll的请求参数不能为空");
                BizCheckUtil.checkNotBlank((String) baseGetRequest.getId(), "id不能为空");
            }

            @Override
            public void executeService() {
                final SoldierTpAllDO soldierTpAllDO = soldierTpAllService.get((String) baseGetRequest.getId());
                final SoldierTpAllDTO remoteObj = SoldierTpAllProviderConverter.convertResponseDO2DTO(soldierTpAllDO);
                ResponseUtils.setupSuccessResponse(baseResponse, remoteObj);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.SOLDIER_TP_ALL_GET;
            }
        });
        return baseResponse;
    }

    @Override
    public BaseResponse<StatsEmploymentInfo> calculateYear3Employment(BaseGetRequest baseGetRequest) {

        int unemploymentNum = 0;
        int employmentInfo = 0;
        int elseInfo = 0;
        int allNum = 0;
        LinkedHashMap<String, Integer> industryMap = Maps.newLinkedHashMap();

        Date date = org.apache.commons.lang3.time.DateUtils.addMonths(new Date(), -12);
        String unemploymentRegistrationTime = DateUtil.formatDate(date, "yyyy-MM");

        String socialUnemploymentTime = DateUtil.formatDate(org.apache.commons.lang3.time.DateUtils.addMonths(new Date(), -4), "yyyy-MM-dd");

        String id = null;
        if (baseGetRequest != null) {
            id = (String) baseGetRequest.getId();
        }
        List<SoldierTpAllDO> yData = soldierTpAllService.get3YdateOfSocialMore(id);
        allNum = yData.size();
        for (SoldierTpAllDO soldierTpAllDO : yData) {
            if (soldierTpAllDO.isUnemploymentRegistrationFlag()) {

                String unemploymentRegistration = soldierTpAllDO.getUnemploymentRegistration();
                List<UnemploymentRegistrationEntity> unemploymentRegistrationEntities = JSONArray.parseArray(unemploymentRegistration, UnemploymentRegistrationEntity.class);
                for (UnemploymentRegistrationEntity unemploymentRegistrationEntity : unemploymentRegistrationEntities) {

                    if (unemploymentRegistrationEntity.getAae044().compareTo(unemploymentRegistrationTime) > 0 &&
                            "有效".equals(unemploymentRegistrationEntity.getAae100())) {

                        unemploymentNum++;
                        break;
                    }
                }
                continue;
            }

            List<InsuredInfoEntity> insuredInfoEntities = ThirdPartyDealUtils.fileSocialSecurity(soldierTpAllDO.getSocialSecurity());
            if (soldierTpAllDO.isSocialSecurityFlag() && !CollectionUtils.isEmpty(insuredInfoEntities)) {

                InsuredInfoEntity lastOne = insuredInfoEntities.get(0);
                String aae036 = lastOne.getAae036();
                if (aae036.compareTo(socialUnemploymentTime) < 0) {
                    unemploymentNum++;
                }

                String jobTaxCompany = soldierTpAllDO.getJobTaxCompany();
                buildValue(industryMap, jobTaxCompany);

            } else {
                elseInfo++;
            }
        }

        employmentInfo = yData.size() - unemploymentNum - elseInfo;
        StatsEmploymentInfo result = new StatsEmploymentInfo(unemploymentNum, employmentInfo, elseInfo, industryMap);
        result.setAllNum(allNum);
        return ResponseUtils.buildSuccessResponse(result);
    }

    @Override
    public BaseResponse<StatsEmploymentInfo> dealYear3Employment(BaseGetRequest baseGetRequest) {
        boolean lock = redisLock.tryLock("calculateYear3Employment", 60000);
        if (!lock) {
            return null;
        }

        StatsEmploymentInfo dto = soldierDataBuffer.querySoldierDate(new SoldierStatsRequest("330100000000"), StatsDataTypeEnum.SOLDIER_THREE_YEAR, StatsEmploymentInfo.class,
                new AbstractSoldierDateStats<StatsEmploymentInfo>() {
                    @Override
                    public StatsEmploymentInfo basicStatistics(SoldierStatsRequest soldierStatsRequest) {
                        return stats3Year();
                    }
                });


        return ResponseUtils.buildSuccessResponse(dto);
    }

    @Override
    public BaseResponse<StatsEmploymentInfo> dealEmployInfo(SoldierTpAllSearchRequest request) {
        boolean lock = redisLock.tryLock("dealEmployInfo", 60000);
        if (!lock) {
            return null;
        }

        StatsEmploymentInfo dto = soldierDataBuffer.querySoldierDate(new SoldierStatsRequest("330100000000"), StatsDataTypeEnum.SOLDIER_ALL_YEAR, StatsEmploymentInfo.class,
                new AbstractSoldierDateStats<StatsEmploymentInfo>() {
                    @Override
                    public StatsEmploymentInfo basicStatistics(SoldierStatsRequest soldierStatsRequest) {
                        return statsAllYearInfo(request.getStartYear(), request.getEndYear());
                    }
                });


        return ResponseUtils.buildSuccessResponse(dto);
    }

    private StatsEmploymentInfo statsAllYearInfo(String startYear, String endYear) {
        BizCheckUtil.checkNotBlank(startYear, "startyear不能为空");
        try {

            Integer allNum = 0;
            Integer unemploymentRegistrationNum = 0;
            Integer withdrawNum = 0;
            Integer noSocialSecurityNum = 0;
            Integer unemploymentNum = 0;
            Integer employmentNum = 0;
            Integer elseNum = 0;
            LinkedHashMap<String, Integer> industryMap = Maps.newLinkedHashMap();
            LinkedHashMap<String, Integer> withdrawIndustryMap = Maps.newLinkedHashMap();
            LinkedHashMap<String, Integer> employmentIndustryMap = Maps.newLinkedHashMap();

            String unemploymentRegistrationTime = DateUtil.formatDate(org.apache.commons.lang3.time.DateUtils.addMonths(new Date(), -12), "yyyy-MM");

            String socialUnemploymentTime = DateUtil.formatDate(org.apache.commons.lang3.time.DateUtils.addMonths(new Date(), -4), "yyyy-MM-dd");

            List<SoldierTpAllDO> ydate = soldierTpAllService.getAllNotRetired(startYear, endYear);
            for (SoldierTpAllDO soldierTpAllDO : ydate) {
                log.info("route:{}", allNum++);

                if (soldierTpAllDO.isUnemploymentRegistrationFlag()) {

                    String unemploymentRegistration = soldierTpAllDO.getUnemploymentRegistration();
                    List<UnemploymentRegistrationEntity> unemploymentRegistrationEntities = JSONArray.parseArray(unemploymentRegistration, UnemploymentRegistrationEntity.class);
                    for (UnemploymentRegistrationEntity unemploymentRegistrationEntity : unemploymentRegistrationEntities) {
                        if (unemploymentRegistrationEntity.getAae044().compareTo(unemploymentRegistrationTime) > 0 &&
                                "有效".equals(unemploymentRegistrationEntity.getAae100())) {

                            unemploymentNum++;
                            unemploymentRegistrationNum++;
                            break;
                        }
                    }
                }

                if (soldierTpAllDO.isSocialSecurityFlag()) {
                    List<InsuredInfoEntity> insuredInfoEntities = ThirdPartyDealUtils.fileSocialSecurity(soldierTpAllDO.getSocialSecurity());
                    if (CollectionUtils.isEmpty(insuredInfoEntities)) {
                        unemploymentNum++;
                        noSocialSecurityNum++;
                        continue;
                    }
                    InsuredInfoEntity lastOne = insuredInfoEntities.get(0);
                    String aae036 = lastOne.getAae036();
                    if (aae036.compareTo(socialUnemploymentTime) < 0) {
                        unemploymentNum++;
                        withdrawNum++;
                        buildValue(withdrawIndustryMap, soldierTpAllDO.getJobTaxCompany());
                    } else {
                        employmentNum++;
                        buildValue(withdrawIndustryMap, soldierTpAllDO.getJobTaxCompany());
                    }

                    buildValue(employmentIndustryMap, soldierTpAllDO.getJobTaxCompany());

                } else {
                    unemploymentNum++;
                    noSocialSecurityNum++;
                }
            }

            employmentNum = ydate.size() - unemploymentNum;
            StatsEmploymentInfo result = new StatsEmploymentInfo();
            result.setAllNum(allNum);
            result.setUnemploymentRegistrationNum(unemploymentRegistrationNum);
            result.setWithdrawNum(withdrawNum);
            result.setNoSocialSecurityNum(noSocialSecurityNum);
            result.setUnemploymentNum(unemploymentNum);
            result.setEmploymentNum(employmentNum);
            result.setElseNum(elseNum);
            result.setIndustryMap(industryMap);
            result.setWithdrawIndustryMap(withdrawIndustryMap);
            result.setEmploymentIndustryMap(employmentIndustryMap);

            result.setPioneerNum(soldierTpAllService.countShareholder(startYear, endYear));

            return result;
        } catch (Exception e) {
            log.error("error:{}", e);
            throw e;
        }
    }

    private StatsEmploymentInfo stats3Year() {
        Integer allNum = 0;
        Integer unemploymentRegistrationNum = 0;
        Integer withdrawNum = 0;
        Integer noSocialSecurityNum = 0;
        Integer unemploymentNum = 0;
        Integer employmentNum = 0;
        Integer elseNum = 0;
        LinkedHashMap<String, Integer> industryMap = Maps.newLinkedHashMap();
        LinkedHashMap<String, Integer> withdrawIndustryMap = Maps.newLinkedHashMap();
        LinkedHashMap<String, Integer> employmentIndustryMap = Maps.newLinkedHashMap();

        String unemploymentRegistrationTime = DateUtil.formatDate(org.apache.commons.lang3.time.DateUtils.addMonths(new Date(), -12), "yyyy-MM");

        String socialUnemploymentTime = DateUtil.formatDate(org.apache.commons.lang3.time.DateUtils.addMonths(new Date(), -4), "yyyy-MM-dd");

        List<SoldierTpAllDO> ydate = soldierTpAllService.get3Ydate();
        for (SoldierTpAllDO soldierTpAllDO : ydate) {
            allNum++;
            if (soldierTpAllDO.isUnemploymentRegistrationFlag()) {

                String unemploymentRegistration = soldierTpAllDO.getUnemploymentRegistration();
                List<UnemploymentRegistrationEntity> unemploymentRegistrationEntities = JSONArray.parseArray(unemploymentRegistration, UnemploymentRegistrationEntity.class);
                for (UnemploymentRegistrationEntity unemploymentRegistrationEntity : unemploymentRegistrationEntities) {
                    if (unemploymentRegistrationEntity.getAae044().compareTo(unemploymentRegistrationTime) > 0 &&
                            "有效".equals(unemploymentRegistrationEntity.getAae100())) {

                        soldierTpAllService.update3YTest(soldierTpAllDO.getIdCardNo(), "|失业登记：" + unemploymentRegistrationEntity.getAae044());
                        unemploymentNum++;
                        unemploymentRegistrationNum++;
                        break;
                    }
                }
            }

            List<InsuredInfoEntity> insuredInfoEntities = ThirdPartyDealUtils.fileSocialSecurity(soldierTpAllDO.getSocialSecurity());
            if (soldierTpAllDO.isSocialSecurityFlag() && !CollectionUtils.isEmpty(insuredInfoEntities)) {
                InsuredInfoEntity lastOne = insuredInfoEntities.get(0);
                String aae036 = lastOne.getAae036();
                if (aae036.compareTo(socialUnemploymentTime) < 0) {
                    soldierTpAllService.update3YTest(soldierTpAllDO.getIdCardNo(), "|断缴：" + aae036);
                    unemploymentNum++;
                    withdrawNum++;
                    buildValue(withdrawIndustryMap, soldierTpAllDO.getJobTaxCompany());
                } else {
                    employmentNum++;
                    buildValue(withdrawIndustryMap, soldierTpAllDO.getJobTaxCompany());
                }

                buildValue(employmentIndustryMap, soldierTpAllDO.getJobTaxCompany());

            } else {
                soldierTpAllService.update3YTest(soldierTpAllDO.getIdCardNo(), "|未查询到社保");
                unemploymentNum++;
                noSocialSecurityNum++;
            }
        }

        employmentNum = ydate.size() - unemploymentNum;
        StatsEmploymentInfo result = new StatsEmploymentInfo();
        result.setAllNum(allNum);
        result.setUnemploymentRegistrationNum(unemploymentRegistrationNum);
        result.setWithdrawNum(withdrawNum);
        result.setNoSocialSecurityNum(noSocialSecurityNum);
        result.setUnemploymentNum(unemploymentNum);
        result.setEmploymentNum(employmentNum);
        result.setElseNum(elseNum);
        result.setIndustryMap(industryMap);
        result.setWithdrawIndustryMap(withdrawIndustryMap);
        result.setEmploymentIndustryMap(employmentIndustryMap);
        return result;
    }

    private void buildValue(LinkedHashMap<String, Integer> industryMap, String jobTaxCompany) {
        if (Strings.isNotBlank(jobTaxCompany)) {
            List<TaxEnterpriseInfoEntity> taxEnterpriseInfoEntities = JSONArray.parseArray(jobTaxCompany, TaxEnterpriseInfoEntity.class);
            for (TaxEnterpriseInfoEntity taxEnterpriseInfoEntity : taxEnterpriseInfoEntities) {
                addKeyCount(industryMap, taxEnterpriseInfoEntity.getIndustry());
            }
        }
    }


    public LinkedHashMap<String, Integer> sortLinkedMapByValue(LinkedHashMap<String, Integer> map) {
        List<Map.Entry<String, Integer>> entries = Lists.newArrayList(map.entrySet());
        Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        });

        LinkedHashMap<String, Integer> result = Maps.newLinkedHashMap();
        for (Map.Entry<String, Integer> entry : entries) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }


    private void addKeyCount(Map<String, Integer> map, String key) {
        Integer integer = map.get(key);
        if (integer != null) {
            map.put(key, integer + 1);
        } else {
            map.put(key, 1);
        }
    }

    public static void main(String[] args) {
        System.out.println(DateUtil.formatDate(org.apache.commons.lang3.time.DateUtils.addMonths(new Date(), -4), "yyyy-MM-dd"));

    }


    @Override
    public BaseResponse<String> insertSoldierTpAll(final SoldierTpAllInsertRequest insertRequest) {

        final BaseResponse<String> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(insertRequest, "新增SoldierTpAll的请求参数不能为空");
            }

            @Override
            public void executeService() {
                final SoldierTpAllDO soldierTpAllDO = SoldierTpAllProviderConverter.convertRequestIO2DO(insertRequest);
                soldierTpAllService.insert(soldierTpAllDO);
                ResponseUtils.setupSuccessResponse(baseResponse, soldierTpAllDO.getId());
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.SOLDIER_TP_ALL_INSERT;
            }
        });
        return baseResponse;
    }

    @Override
    public BaseResponse<String> insertSoldierTpALLInTestTable(SoldierTpAllInsertRequest insertRequest) {

        ThreadPoolManager.getInstance().submit(new Runnable() {
            @Override
            public void run() {
                List<SoldierTpAllDO> soldierTpAllDOS = soldierTpAllService.listAllIdCardNoInTestTable();
                int loop = 1;
                for (SoldierTpAllDO soldierTpAllDO : soldierTpAllDOS) {
                    log.info("将test表里面的数据插入到数据库loop:{}", loop++);
                    try {
                        soldierExtraInfoRefresher.refreshByIdCardNoNotCheck(soldierTpAllDO.getIdCardNo(), soldierTpAllDO.getNickName());
                    } catch (Exception e) {
                        log.error("导入错误：{}", e);
                    }
                }
            }
        });

        return ResponseUtils.buildSuccessResponse("");
    }

    @Override
    public BaseResponse<String> exportDetail(SimpleApiRequest request) {

        BizCheckUtil.checkNotNull(request, "请求不能为空");
        BizCheckUtil.checkNotNull(request.getUrl(), "url不能为空");

        try {
            String url = request.getUrl();
            url = url.replace("115.227.32.11", "172.18.102.62");
            URL source = new URL(url);
            InputStream inputStream = source.openStream();
            ExcelReader reader = ExcelUtil.getReader(inputStream);

            final List<List<Object>> read = reader.read();
            String[] strings = {"序号", "姓名", "身份证号"};
            checkSoldierImportTemplate(read.get(0), strings);

            Date date = org.apache.commons.lang3.time.DateUtils.addMonths(new Date(), -3);
            String startCalDateTime = DateUtil.formatDate(date, "yyyy-MM");

            ThreadPoolManager.getInstance().submit(new Runnable() {
                @Override
                public void run() {

                    List<List<Object>> list = read.subList(1, read.size());

                    for (List<Object> objects : list) {
                        for (int i = objects.size(); i < strings.length; i++) {
                            objects.add(null);
                        }
                    }


                    List<String> result = new ArrayList<>();
                    for (List<Object> objects : list) {
                        try {
                            List<String> item = Lists.newArrayList();

                            Object index = objects.get(0);
                            String realName = (String) objects.get(1);
                            String idCardNo = (String) objects.get(2);

                            item.add(String.valueOf(index));
                            item.add(realName);
                            item.add(idCardNo);

                            String birthYear = idCardNo.substring(6, 10);
                            Integer age = 2021 - Integer.valueOf(birthYear);
                            if (age >= 60) {
                                item.add("");
                                item.add("");
                                item.add("");
                                item.add("");
                                item.add("");
                                continue;
                            }

                            item.add(String.valueOf(age));

                            SoldierTpAllDO soldierTpAllDO = soldierTpAllService.getByIdCardNo(idCardNo);
                            if (soldierTpAllDO == null) {
                                soldierTpAllDO = soldierExtraInfoRefresher.refreshByIdCardNo(idCardNo);
                            }

                            if (soldierTpAllDO.isSocialSecurityFlag()) {
                                List<InsuredInfoEntity> insuredInfoEntities = ThirdPartyDealUtils.fileSocialSecurity(soldierTpAllDO.getSocialSecurity());
                                InsuredInfoEntity lastOne = insuredInfoEntities.get(0);
                                String aae036 = lastOne.getAae036();

                                if (aae036.compareTo(startCalDateTime) < 0) {
                                    item.add("断缴");
                                } else {
                                    item.add("正常");
                                }
                                item.add(aae036);
                                item.add(lastOne.getAab004());
                            } else {
                                item.add("无记录");
                                item.add("");
                                item.add("");
                            }

                            if (soldierTpAllDO.isShareholderFlag()) {
                                List<ShareholderEntity> shareholderEntities = JSONArray.parseArray(soldierTpAllDO.getShareholder(), ShareholderEntity.class);
                                ShareholderEntity shareholderEntity = shareholderEntities.get(0);
                                item.add(shareholderEntity.getPositionCn());
                                item.add(shareholderEntity.getEntname());
                            } else {
                                item.add("无");
                                item.add("");
                            }

                            result.add(String.join(",", item));
                        } catch (Exception e) {
                            log.error("导入错误：{}", e);
                        }
                    }
                    for (String s : result) {
                        System.out.println(s + "\n");
                    }
                    for (String s : result) {
                        log.info(s + "\n");
                    }
                }
            });

        } catch (BizException e) {
            log.error("导入数据发生异常", e);
            throw e;
        } catch (Exception e) {
            log.error("导入数据发生异常", e);
            throw new BizException(ErrorCodeEnum.ILLEGAL_PARAM);
        }
        return ResponseUtils.buildSuccessResponse("处理中");
    }

    private void checkSoldierImportTemplate(List<Object> headers, String... names) {
        for (int i = 0; i < names.length; i++) {
            BizCheckUtil.checkIsTrue(((String) headers.get(i)).startsWith(names[i]), "模板错误");
        }
    }


    @Override
    public BaseResponse<Integer> updateSoldierTpAll(final SoldierTpAllUpdateRequest updateRequest) {

        final BaseResponse<Integer> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(updateRequest, "修改SoldierTpAll的请求参数不能为空");
                BizCheckUtil.checkNotBlank(updateRequest.getId(), "id不能为空");
                BizCheckUtil.checkNotBlank(updateRequest.getModifierId(), "操作人不能为空");
                BizCheckUtil.checkNotBlank(updateRequest.getModifierType(), "操作人类型不能为空");
            }

            @Override
            public void executeService() {
                SoldierTpAllDO soldierTpAllDO = SoldierTpAllProviderConverter.convertRequestUO2DO(updateRequest);
                Integer affectRowNum = soldierTpAllService.update(soldierTpAllDO);
                ResponseUtils.setupSuccessResponse(baseResponse, affectRowNum);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.SOLDIER_TP_ALL_UPDATE;
            }
        });
        return baseResponse;
    }

    @Override
    public BaseResponse<Integer> setUnemploymentRegistrationTime(SoldierTpAllUpdateRequest soldierTpAllUpdateRequest) {

        ThreadPoolManager.getInstance().submit(new Runnable() {
            @Override
            public void run() {
                List<SoldierTpAllDO> unemploymentRegistration = soldierTpAllService.listAllUnemploymentRegistration(null);
                for (SoldierTpAllDO soldierTpAllDO : unemploymentRegistration) {
                    log.info("刷新：{}", soldierTpAllDO);
                    String str = soldierTpAllDO.getUnemploymentRegistration();
                    if (Strings.isNotBlank(str)) {
                        List<UnemploymentRegistrationEntity> unemploymentRegistrationEntities = JSONArray.parseArray(str, UnemploymentRegistrationEntity.class);
                        Collections.sort(unemploymentRegistrationEntities, new Comparator<UnemploymentRegistrationEntity>() {
                            @Override
                            public int compare(UnemploymentRegistrationEntity o1, UnemploymentRegistrationEntity o2) {
                                return o2.getAae044().compareTo(o1.getAae044());
                            }
                        });
                        String aae044 = unemploymentRegistrationEntities.get(0).getAae044();
                        soldierTpAllService.updateUnemploymentRegistrationTime(soldierTpAllDO.getIdCardNo(), aae044);
                    }
                }
            }
        });

        return ResponseUtils.buildSuccessResponse(0);
    }

    @Override
    public BaseResponse<Integer> updateLatestSocialTime(SoldierTpAllUpdateRequest request) {

        ThreadPoolManager.getInstance().submit(new Runnable() {
            @Override
            public void run() {
                int i = 1;
                SoldierBasicInfoBSearcher searcher = new SoldierBasicInfoBSearcher(i++, 10000);
                List<SoldierTpAllDO> soldierTpAllDOS = soldierTpAllService.listAllSocialSecurity(searcher);
                while (!CollectionUtils.isEmpty(soldierTpAllDOS)) {
                    for (SoldierTpAllDO soldierTpAllDO : soldierTpAllDOS) {
                        if (Strings.isBlank(soldierTpAllDO.getSocialSecurity())) {
                            continue;
                        }

                        List<InsuredInfoEntity> insuredInfoEntities = ThirdPartyDealUtils.fileSocialSecurity(soldierTpAllDO.getSocialSecurity());
                        if (CollectionUtils.isEmpty(insuredInfoEntities)) {
                            continue;
                        }
                        InsuredInfoEntity lastOne = insuredInfoEntities.get(0);
                        String aae036 = lastOne.getAae036();

                        soldierTpAllDO.setLatestSocialTime(aae036);
                        soldierTpAllService.updateLatestSocialTime(soldierTpAllDO.getIdCardNo(), aae036);
                    }
                    searcher = new SoldierBasicInfoBSearcher(i++, 10000);
                    soldierTpAllDOS = soldierTpAllService.listAllSocialSecurity(searcher);
                }
            }
        });

        return ResponseUtils.buildSuccessResponse(0);
    }


    @Override
    public BaseResponse<Integer> deleteSoldierTpAll(final BaseDeleteRequest deleteRequest) {

        final BaseResponse<Integer> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(deleteRequest, "逻辑删除SoldierTpAll的请求参数不能为空");
                BizCheckUtil.checkNotBlank((String) deleteRequest.getId(), "id不能为空");
                BizCheckUtil.checkNotBlank(deleteRequest.getModifierType(), "操作人类型不能为空");
                BizCheckUtil.checkNotBlank((String) deleteRequest.getModifierId(), "操作人不能为空");
            }

            @Override
            public void executeService() {
                final Integer affectRowNum = soldierTpAllService.delete((String) deleteRequest.getId(), deleteRequest.getModifierType(), (String) deleteRequest.getModifierId());
                ResponseUtils.setupSuccessResponse(baseResponse, affectRowNum);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.SOLDIER_TP_ALL_DELETE_LOGICALLY;
            }
        });
        return baseResponse;
    }

    @Override
    public String getLastSocial(String idCardNo) {


        SoldierTpAllDO soldierTpAllDO = soldierTpAllService.getByIdCardNo(idCardNo);
        if (soldierTpAllDO == null) {
            soldierTpAllDO = soldierExtraInfoRefresher.refreshByIdCardNo(idCardNo);
            if (soldierTpAllDO == null) {
                return null;
            }
        }
        List<InsuredInfoEntity> insuredInfoEntities = ThirdPartyDealUtils.fileSocialSecurity(soldierTpAllDO.getSocialSecurity());
        if (CollectionUtils.isEmpty(insuredInfoEntities)) {
            return null;
        }
        InsuredInfoEntity lastOne = insuredInfoEntities.get(0);
        String aae036 = lastOne.getAae036();
        return aae036;
    }

    @Override
    public StatsEmploymentInfo countSocialSecurity(String adminAreaCode) {
        List<SoldierTpAllDO> soldierTpAllDOS = soldierTpAllService.listNotRetiredSocialSecurity(adminAreaCode, null);
        Date date = org.apache.commons.lang3.time.DateUtils.addMonths(new Date(), -3);
        String startCalDateTime = DateUtil.formatDate(date, "yyyy-MM");

        Integer withdrawNum = 0;
        Integer noSocialSecurityNum = 0;
        Integer employmentNum = 0;

        for (SoldierTpAllDO soldierTpAllDO : soldierTpAllDOS) {
            if (soldierTpAllDO.isSocialSecurityFlag()) {
                List<InsuredInfoEntity> insuredInfoEntities = ThirdPartyDealUtils.fileSocialSecurity(soldierTpAllDO.getSocialSecurity());
                if (CollectionUtils.isEmpty(insuredInfoEntities)) {
                    noSocialSecurityNum++;
                    continue;
                }
                InsuredInfoEntity lastOne = insuredInfoEntities.get(0);
                String aae036 = lastOne.getAae036();

                if (aae036.compareTo(startCalDateTime) < 0) {
                    withdrawNum++;
                } else {
                    employmentNum++;
                }
            } else {
                noSocialSecurityNum++;
            }
        }

        StatsEmploymentInfo result = new StatsEmploymentInfo();
        result.setWithdrawNum(withdrawNum);
        result.setNoSocialSecurityNum(noSocialSecurityNum);
        result.setEmploymentNum(employmentNum);
        return result;
    }

    @Override
    public BaseResponse<String> exportJcCompany(SoldierTpAllSearchRequest searchRequest) {


        CommonTmpInfoDO infoDO = new CommonTmpInfoDO();
        infoDO.setTitle("军创企业导出");
        commonTmpInfoService.insert(infoDO);

        ThreadPoolManager.getInstance().submit(new Runnable() {
            @Override
            public void run() {
                try {
                    List<CommonAdminAreaDO> subAreaList = commonAdminAreaService.findSubAreaList("330100000000");


                    Map<String, Integer> companyMap = Maps.newLinkedHashMap();

                    IScrollGet<SoldierTpAllDO> scrollGetTask = new IScrollGet<SoldierTpAllDO>() {
                        SoldierTpAllBSearcher ss = new SoldierTpAllBSearcher(1, 500);

                        @Override
                        public List<SoldierTpAllDO> scrollGetFunc(Integer pageNo) {
                            ss.setPageNo(pageNo);
                            ss.setAdminAreaCode("3301");
                            ss.setFlag(true);
                            List<SoldierTpAllDO> soldierTpAllDOS = soldierTpAllService.searchNotRetiredSocialSecurity(ss);
                            return soldierTpAllDOS;
                        }
                    };

                    int loop = 1;
                    Iterator<SoldierTpAllDO> dataIterator = scrollGetTask.getDataIterator();
                    while (dataIterator.hasNext()) {
                        log.info("{}", loop++);
                        SoldierTpAllDO next = dataIterator.next();
                        String companySocialNotGtldz = soldierUnemploymentRegistrationInfoProvider.getCompanySocialNotGtldz(next.getSocialSecurity());
                        if (Strings.isNotBlank(companySocialNotGtldz)) {
                            companyMap.merge(companySocialNotGtldz, 1, Integer::sum);
                        }
                    }

                    for (Map.Entry<String, Integer> entry : companyMap.entrySet()) {
                        log.info("企业情况：{}-{}", entry.getKey(), entry.getValue());
                    }

                    List<String> headers = Lists.newArrayList("姓名", "身份证", "退役时间", "老兵分区", "老兵职位", "单位详细名称", "统一信用代码"
                            , "成立时间", "所属行业", "地址", "单位所在地行政区划", "公司类型", "经营范围", "企业规模", "经营状态", "退役军人数", "企业联系方式");
                    List<List<String>> data = Lists.newArrayList();

                    IScrollGet<SoldierTpAllDetailBO> companyScroll = new IScrollGet<SoldierTpAllDetailBO>() {
                        SoldierTpAllBSearcher searcher = new SoldierTpAllBSearcher(1, 1000);

                        @Override
                        public List<SoldierTpAllDetailBO> scrollGetFunc(Integer pageNo) {
                            searcher.setPageNo(pageNo);
                            List<SoldierTpAllDetailBO> soldierTpAllDetailBOS = soldierTpAllService.searchShareholder(searcher);
                            return soldierTpAllDetailBOS;
                        }
                    };
                    loop = 1;
                    Iterator<SoldierTpAllDetailBO> companyIterator = companyScroll.getDataIterator();
                    while (companyIterator.hasNext()) {
                        log.info("-{}", loop++);
                        SoldierTpAllDetailBO detailBO = companyIterator.next();
                        try {

                            if (detailBO.isSocialSecurityFlag() == true) {
                                String companySocialNotGtldz = soldierUnemploymentRegistrationInfoProvider.getCompanySocialNotGtldz(detailBO.getSocialSecurity());
                                if (companySocialNotGtldz == null) {
                                    continue;
                                }
                            }
                            List<String> item = Lists.newArrayList();
                            item.add(detailBO.getRealName());
                            item.add(detailBO.getIdCardNo());

                            if (detailBO.getRetireDatetime() != null) {
                                item.add(DateUtil.formatDate(detailBO.getRetireDatetime()));
                            } else {
                                item.add("");
                            }

                            String s = AdminAreaCodeUtils.cutAreaCode(detailBO.getResidentAdminAreaCode(), "3");
                            String fillAreaCode = AdminAreaCodeUtils.fillAreaCode(s);
                            String areaName = findMatchArea(fillAreaCode, subAreaList);
                            item.add(areaName);

                            List<ShareholderEntity> shareholderEntities = JSONArray.parseArray(detailBO.getShareholder(), ShareholderEntity.class);
                            ShareholderEntity shareholderEntity = shareholderEntities.get(0);
                            item.add(shareholderEntity.getPositionCn());
                            item.add(shareholderEntity.getEntname());
                            item.add(shareholderEntity.getUniscid());

                            List<EnterpriseInfoEntity> enterpriseInfoEntities = JSONArray.parseArray(detailBO.getCompany(), EnterpriseInfoEntity.class);
                            if (CollectionUtils.isEmpty(enterpriseInfoEntities)) {
                                item.add("");
                                item.add("");
                                item.add("");
                                item.add("");
                                item.add("");
                                item.add("");
                                item.add("");
                                item.add("");
                                item.add("0");
                            } else {
                                EnterpriseInfoEntity enterpriseInfoEntity = enterpriseInfoEntities.get(0);

                                item.add(enterpriseInfoEntity.getEstDate());
                                item.add(enterpriseInfoEntity.getTradeCode());
                                item.add(enterpriseInfoEntity.getCompanyAddr());

                                String ad = findMatchAreaByAddress(enterpriseInfoEntity.getCompanyAddr(), subAreaList);
                                item.add(ad);
                                item.add(enterpriseInfoEntity.getCompanyType());
                                item.add(enterpriseInfoEntity.getOpScope());
                                item.add(enterpriseInfoEntity.getRegisterAmount());
                                item.add(enterpriseInfoEntity.getOperatingStatus());
                                Integer integer = companyMap.get(enterpriseInfoEntity.getCompanyName());
                                if (integer == null) {
                                    integer = 0;
                                }
                                item.add(String.valueOf(integer));
                            }

                            List<TaxEnterpriseInfoEntity> taxEnterpriseInfoEntities = JSONArray.parseArray(detailBO.getShareTaxCompany(), TaxEnterpriseInfoEntity.class);
                            if (CollectionUtils.isEmpty(taxEnterpriseInfoEntities)) {
                                item.add("");
                            } else {
                                TaxEnterpriseInfoEntity taxEnterpriseInfoEntity = taxEnterpriseInfoEntities.get(0);
                                item.add(taxEnterpriseInfoEntity.getPhone());
                            }
                            data.add(item);
                        } catch (Exception e) {
                            log.error("err:{}", e);
                        }

                    }

                    ExcelResultBO excelResultBO = new ExcelResultBO("一人一档", headers, data);

                    infoDO.setContent(JSON.toJSONString(excelResultBO));
                    infoDO.setUsed(false);
                    commonTmpInfoService.update(infoDO);
                } catch (Exception e) {
                    log.error("{}", e);
                }
            }
        });

        return ResponseUtils.buildSuccessResponse(infoDO.getId());
    }

    @Override
    public CsdnLatestJobScreenDTO calculateJcqyInfo(String adminAreaCode) {
        CsdnLatestJobScreenDTO dto = new CsdnLatestJobScreenDTO();

        Integer militaryEnterpriseNum = 0;
        Integer lastYearPioneerNum = 0;
        LinkedHashMap<String, Integer> pioneerTimeQTrendNum = new LinkedHashMap<>();
        LinkedHashMap<String, Integer> militaryIndustryMap = new LinkedHashMap<>();

        IScrollGet<SoldierTpAllDetailBO> companyScroll = new IScrollGet<SoldierTpAllDetailBO>() {
            SoldierTpAllBSearcher searcher = new SoldierTpAllBSearcher(1, 10000);

            @Override
            public List<SoldierTpAllDetailBO> scrollGetFunc(Integer pageNo) {
                searcher.setPageNo(pageNo);
                searcher.setAdminAreaCode(adminAreaCode);
                List<SoldierTpAllDetailBO> soldierTpAllDetailBOS = soldierTpAllService.searchShareholder(searcher);
                return soldierTpAllDetailBOS;
            }
        };
        int loop = 1;
        Iterator<SoldierTpAllDetailBO> companyIterator = companyScroll.getDataIterator();
        while (companyIterator.hasNext()) {
            log.info("-{}", loop++);
            SoldierTpAllDetailBO detailBO = companyIterator.next();
            try {

                if (detailBO.isSocialSecurityFlag() == true) {
                    String companySocialNotGtldz = soldierUnemploymentRegistrationInfoProvider.getCompanySocialNotGtldz(detailBO.getSocialSecurity());
                    if (companySocialNotGtldz == null) {
                        continue;
                    }
                }

                Date currentYearStartTime = DateUtils.getCurrentYearStartTime();
                Date lastYearStartTime = DateUtils.addYears(currentYearStartTime, -1);
                String startYearStr = DateUtil.formatDate(lastYearStartTime, "yyyy-MM-dd");
                String endYearStr = DateUtil.formatDate(currentYearStartTime, "yyyy-MM-dd");

                List<String> quarters = listQuarter();
                if (Strings.isNotBlank(detailBO.getCompany())) {
                    List<EnterpriseInfoEntity> enterpriseInfoEntities = JSONArray.parseArray(detailBO.getCompany(), EnterpriseInfoEntity.class);
                    if (!CollectionUtils.isEmpty(enterpriseInfoEntities)) {
                        for (EnterpriseInfoEntity enterpriseInfoEntity : enterpriseInfoEntities) {
                            militaryEnterpriseNum++;
                            militaryIndustryMap.merge(enterpriseInfoEntity.getTradeCode(), 1, Integer::sum);

                            String estDate = enterpriseInfoEntity.getEstDate();
                            if (startYearStr.compareTo(estDate) < 0 && endYearStr.compareTo(estDate) > 0) {
                                lastYearPioneerNum++;
                            }

                            String qtime = getBetweenTimeStart(estDate, quarters);
                            if (qtime != null) {
                                pioneerTimeQTrendNum.merge(qtime, 1, Integer::sum);
                            }

                        }
                    }
                }
            } catch (Exception e) {
                log.error("{}", e);
            }
        }




        return dto;
    }

    @Override
    public String getDifficultyInfo(String idCardNo) {
        SoldierBasicInfoBSearcher searcher = new SoldierBasicInfoBSearcher(1, Integer.MAX_VALUE);
        searcher.setColumn("is_subsistence_allowance_flag,subsistence_allowance,id_card_no,is_low_side_flag,low_side,is_extremely_poor_flag,extremely_poor");
        searcher.setIdCardNo(idCardNo);
        List<SoldierTpAllDO> soldierTpAllDOS = soldierTpAllService.searchItem(searcher);
        if (CollectionUtils.isEmpty(soldierTpAllDOS)) {
            return null;
        }
        SoldierTpAllDO soldierTpAllDO = soldierTpAllDOS.get(0);
        if (soldierTpAllDO.isSubsistenceAllowanceFlag()) {
            return "低保";
        }
        if (soldierTpAllDO.isLowSideFlag()) {
            return "低边";
        }
        if (soldierTpAllDO.isExtremelyPoorFlag()) {
            return "特困";
        }

        return null;
    }

    @Override
    public BaseResponse<String> exportHouseHoldInfo(SimpleApiRequest request) {

        BizCheckUtil.checkNotNull(request, "请求不能为空");
        BizCheckUtil.checkNotNull(request.getUrl(), "url不能为空");

        try {
            String url = request.getUrl();
            url = url.replace("115.227.32.11", "172.18.102.62");
            URL source = new URL(url);
            InputStream inputStream = source.openStream();
            ExcelReader reader = ExcelUtil.getReader(inputStream);
            final List<List<Object>> read = reader.read();

            ThreadPoolManager.getInstance().submit(new Runnable() {

                @Override
                public void run() {
                    List<String> result = Lists.newArrayList();
                    for (int i = 1; i < read.size(); i++) {
                        try {
                            List<Object> objects = read.get(i);
                            String name = objects.get(0).toString();
                            String idCardNo = objects.get(1).toString();
                            List<SoldierNewHouseholdRegistrationInfoDO> householdRegistrationInfoDOS =
                                    thirdPartyService.queryNewHouseholdRegistrationInfo(idCardNo, name);
                            if (!CollectionUtils.isEmpty(householdRegistrationInfoDOS)) {
                                SoldierNewHouseholdRegistrationInfoDO soldierNewHouseholdRegistrationInfoDO = householdRegistrationInfoDOS.get(0);
                                String gafj = soldierNewHouseholdRegistrationInfoDO.getIssue_mecha();
                                result.add(String.format("%s,A%s,%s,%s", name, idCardNo, gafj,soldierNewHouseholdRegistrationInfoDO.getHshld_addr()));
                            } else {
                                result.add(String.format("%s,A%s, , ", name, idCardNo));
                            }
                        } catch (Exception e) {
                            log.error("{}",e);
                        }
                    }
                    for (String s : result) {
                        log.info("-----:{}", s);
                    }
                }
            });

        } catch (Exception e) {
            log.error("{}", e);
        }
        return ResponseUtils.buildSuccessResponse("");
    }

    private String getBetweenTimeStart(String estDate, List<String> quarters) {
        for (String quarter : quarters) {
            String[] split = quarter.split(",");
            if (split[0].compareTo(estDate) < 0 && split[1].compareTo(estDate) > 0) {
                return split[2];
            }
        }
        return null;
    }

    private List<String> listQuarter() {
        List<String> list = Lists.newArrayList();
        Date afterTime = DateUtils.getCurrentQuarterStartTime();
        for (int i = 0; i < 4; i++) {
            Date beforeTime = DateUtils.addMonths(afterTime, -3);
            String s = cn.hutool.core.date.DateUtil.yearAndQuarter(beforeTime);
            String quarterStr = s.substring(0, 4) + "-Q" + s.substring(4, 5);

            String e = DateUtil.formatDate(beforeTime, "yyyy-MM-dd") + "," + DateUtil.formatDate(afterTime, "yyyy-MM-dd") + "," + quarterStr;
            list.add(e);
            afterTime = beforeTime;
        }
        return list;
    }


    private String findMatchArea(String fillAreaCode, List<CommonAdminAreaDO> subAreaList) {
        for (CommonAdminAreaDO commonAdminAreaDO : subAreaList) {
            if (fillAreaCode.equals(commonAdminAreaDO.getId())) {
                return commonAdminAreaDO.getValue();
            }
        }
        return "杭州市";
    }

    private String findMatchAreaByAddress(String address, List<CommonAdminAreaDO> subAreaList) {
        return findMatchArea(convertAdminAreaCodeFromAddress(address, subAreaList), subAreaList);
    }

    private String convertAdminAreaCodeFromAddress(String address, List<CommonAdminAreaDO> subAreaList) {
        String hzAreaCode = "330100000000";
        if (Strings.isEmpty(address)) {
            return hzAreaCode;
        }

        Map<String, String> valueMap = Maps.newHashMap();
        for (CommonAdminAreaDO commonAdminAreaDO : subAreaList) {
            String value = commonAdminAreaDO.getValue();
            value = removeCommonAreaChar(value);
            valueMap.put(value, commonAdminAreaDO.getId());
        }

        for (String s : valueMap.keySet()) {
            if (address.contains(s)) {
                return valueMap.get(s);
            }
        }
        return hzAreaCode;
    }

    private String removeCommonAreaChar(String value) {
        if (Strings.isEmpty(value)) {
            return value;
        }
        value = value.replace("市", "");
        value = value.replace("县", "");
        return value;
    }
}
